package com.taysear.parcel;

import javax.persistence.EntityManager;


import com.taysear.parcel.domain.Customer;
import com.taysear.parcel.fieldfactory.CustomerFieldFactory;
import com.taysear.parcel.util.Constants;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.JPAContainerFactory;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.filter.Compare.Equal;
import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.themes.Runo;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
public class ParcelForm2 extends VerticalLayout{
	ParcelApplication app;
	VerticalLayout step1 = new VerticalLayout();
	VerticalLayout step2 = new VerticalLayout();
	VerticalLayout step3 = new VerticalLayout();
	VerticalLayout step4 = new VerticalLayout();
	VerticalLayout step5 = new VerticalLayout();
	VerticalLayout step6 = new VerticalLayout();
	Customer sender = null;
	Customer receiver = null;
	
	public ParcelForm2(final ParcelApplication app) {
		super();
		this.app = app;
		loadStep1();
		setSpacing(true);
	}
	
	private void loadStep1() {
		final Form form = new Form();
		form.setCaption("Create parcel step 1");
		addComponent(form);
		
		final TextField senderTel = new TextField("Sender tel");
		senderTel.focus();
		senderTel.setRequired(true);
		senderTel.setRequiredError("Please enter a sender tel");
		senderTel.setWidth(Constants.COMMON_FIELD_WIDTH);
		senderTel.addValidator(Constants.telValidator);
		senderTel.setImmediate(true);
		form.addField("senderTel", senderTel);
		step1.addComponent(form);
		
		Button continueToStep2Btn = new Button("Continue");
		continueToStep2Btn.addStyleName("blueButton");
		continueToStep2Btn.setDisableOnClick(true);
		continueToStep2Btn.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				if(form.isValid()){
					String sTel = senderTel.getValue().toString();
					
					removeAllComponents();
					loadStep2(sTel);
				}else {
					app.showNotification(Constants.ME_FORM_FIELDS_REQUIRED);
               	}
				event.getButton().setEnabled(true);
			}
		});
		step1.addComponent(continueToStep2Btn);
		addComponent(step1);
	}
	
	private void loadStep2(String customerTel) {
		step2.removeAllComponents();
		JPAContainer<Customer> customerContainer = JPAContainerFactory.make(Customer.class, app.PERSISTENCE_UNIT);
		customerContainer.addContainerFilter(new Equal("tel1", customerTel));
		
		final Button backToStep1Btn = new Button("Back");
		backToStep1Btn.setDisableOnClick(true);
		backToStep1Btn.addStyleName("redButton");
		backToStep1Btn.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
            	removeAllComponents();
            	addComponent(step1);
            	event.getButton().setEnabled(true);
            }
		});
		
		final Button continueToStep3Btn = new Button("Continue");
		continueToStep3Btn.setDisableOnClick(true);
		continueToStep3Btn.addStyleName("blueButton");
		continueToStep3Btn.setEnabled(false);
		continueToStep3Btn.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
            	removeAllComponents();
            	loadStep3();
            	event.getButton().setEnabled(true);
            }
		});
		
		if(customerContainer.size() == 0) { // no customer found for this tel, is new customer
			HorizontalLayout newCustomerDetailLayout = new HorizontalLayout();
			newCustomerDetailLayout.setSpacing(true);
			
			final Form form = new Form();
			form.setCaption("Create parcel step 2, sender details");
			
			sender = new Customer();
			sender.setTel1(customerTel);

			CustomerFieldFactory customerFieldFactory = new CustomerFieldFactory();
			customerFieldFactory.tel1.setReadOnly(true);
			form.setFormFieldFactory(customerFieldFactory);
			
			BeanItem<Customer> beanItem = new BeanItem<Customer>(sender);
			String[] columns = {"firstname", "lastname", "idNumber", "address", "postcode", "city", "tel1" };
			form.setItemDataSource(beanItem);
			form.setVisibleItemProperties(columns);
			
			final Button saveBtn = new Button("Save");
			saveBtn.setDisableOnClick(true);
			saveBtn.addStyleName("blueButton");
			
			HorizontalLayout footer = (HorizontalLayout) form.getFooter();
			footer.setSpacing(true);
			footer.addComponent(saveBtn);
			
			newCustomerDetailLayout.addComponent(form);
			
			final CheckBox registerNewCustomer = new CheckBox("Register new customer");
			registerNewCustomer.setImmediate(true);
			newCustomerDetailLayout.addComponent(registerNewCustomer);
			
			step2.addComponent(newCustomerDetailLayout);
			
			saveBtn.addListener(new Button.ClickListener() {
	            public void buttonClick(ClickEvent event) {
	            	if(form.isValid()) {
	            		EntityManager em = app.em;
	            		try{
	            			em.getTransaction().begin();
	            			
	            			sender = new Customer();
	            			sender.setFirstname(form.getField("firstname").getValue().toString());
	            			sender.setLastname(form.getField("lastname").getValue().toString());
	            			sender.setIdNumber(form.getField("idNumber").getValue().toString());
	            			sender.setAddress((String) form.getField("address").getValue());
	            			sender.setPostcode((String) form.getField("postcode").getValue());
	            			sender.setCity((String) form.getField("city").getValue());
	            			sender.setTel1(form.getField("tel1").getValue().toString());
	            			
	            			em.persist(sender);
	            			if((Boolean) registerNewCustomer.getValue()) {
	            				em.getTransaction().commit();
	            				app.showNotification(Constants.SUCCESSFULLY_SAVED_MESSAGE);
	            			}
	            			else
	            				em.getTransaction().rollback();
	            			continueToStep3Btn.setEnabled(true);
	            			backToStep1Btn.setEnabled(false);
	            		} catch (Exception e) {
	            			app.showNotification(Constants.ME_FORM_DATA);
	            			em.getTransaction().rollback();
	            			e.printStackTrace();
	            			saveBtn.setEnabled(true);
	            		}
	            	} else {
	            		app.showNotification(Constants.ME_FORM_FIELDS_REQUIRED);
	            		saveBtn.setEnabled(true);
	            	}
	            }
			});
		} else if(customerContainer.size() == 1) { // use found customer detail to find possible receivers and display sender info
			Panel panel = new Panel("Sender details");
			panel.addStyleName(Runo.PANEL_LIGHT);
			sender = customerContainer.getItem(customerContainer.firstItemId()).getEntity();
        	String customerDetials = "<ul><li>Name: <b>" +sender.getFirstname() +" "+ sender.getLastname() +"</b></li>" +
        					  	   "<li>Address: <b>"+ sender.getAddress() +" "+ sender.getCity() +"</b></li>" +
        					  	   "<li>Tel: <b>"+ sender.getTel1() +"</b></li>" +
        					  "</ul>";
        	panel.addComponent(new Label(customerDetials, Label.CONTENT_XHTML));
        	step2.addComponent(panel);
        	continueToStep3Btn.setEnabled(true);
		} else {
			app.showNotification("This number is used by more then 1 customer.");
		}
		addComponent(step2);
		
		HorizontalLayout buttons = new HorizontalLayout();
		buttons.setSpacing(true);
		buttons.addComponent(backToStep1Btn);
		buttons.addComponent(continueToStep3Btn);
		
		step2.addComponent(buttons);
		
		addComponent(step2);
	}
	
	private void loadStep3() {
		final Form form = new Form();
		form.setCaption("Create parcel step 3 ");
		addComponent(form);
		
		final TextField receiverTel = new TextField("Receiver tel");
		receiverTel.focus();
		receiverTel.setRequired(true);
		receiverTel.setRequiredError("Please enter a receiver tel");
		receiverTel.setWidth(Constants.COMMON_FIELD_WIDTH);
		receiverTel.addValidator(Constants.telValidator);
		receiverTel.setImmediate(true);
		form.addField("receiverTel", receiverTel);
		step3.removeAllComponents();
		step3.addComponent(form);
		
		Button continueToStep4Btn = new Button("Continue");
		continueToStep4Btn.addStyleName("blueButton");
		continueToStep4Btn.setDisableOnClick(true);
		continueToStep4Btn.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				if(form.isValid()){
					String rTel = receiverTel.getValue().toString();
					if(rTel.equalsIgnoreCase(sender.getTel1())) {
						app.showNotification("Sender tel and receiver tel can't be same");
					} else {
						removeAllComponents();
						loadStep4(rTel);
						event.getButton().setEnabled(true);
					}
				}else {
					app.showNotification(Constants.ME_FORM_FIELDS_REQUIRED);
               	}
				event.getButton().setEnabled(true);
			}
		});
		
		HorizontalLayout buttons = new HorizontalLayout();
		buttons.setSpacing(true);
		
		buttons.addComponent(continueToStep4Btn);
		
		step3.addComponent(buttons);
		addComponent(step3);
	}
	
	private void loadStep4(String customerTel) {
		step4.removeAllComponents();
		JPAContainer<Customer> customerContainer = JPAContainerFactory.make(Customer.class, app.PERSISTENCE_UNIT);
		customerContainer.addContainerFilter(new Equal("tel1", customerTel));
		
		final Button backToStep3Btn = new Button("Back");
		backToStep3Btn.setDisableOnClick(true);
		backToStep3Btn.addStyleName("redButton");
		backToStep3Btn.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
            	removeAllComponents();
            	addComponent(step3);
            	event.getButton().setEnabled(true);
            }
		});
		
		final Button continueToStep5Btn = new Button("Continue");
		continueToStep5Btn.setDisableOnClick(true);
		continueToStep5Btn.addStyleName("blueButton");
		continueToStep5Btn.setEnabled(false);
		continueToStep5Btn.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
            	removeAllComponents();
            	loadStep5();
            	event.getButton().setEnabled(true);
            }
		});
		
		if(customerContainer.size() == 0) { // no customer found for this tel, is new customer
			HorizontalLayout newCustomerDetailLayout = new HorizontalLayout();
			newCustomerDetailLayout.setSpacing(true);
			
			final Form form = new Form();
			form.setCaption("Create parcel step 2, receiver details");
			
			Customer customer = new Customer();
			customer.setTel1(customerTel);

			CustomerFieldFactory customerFieldFactory = new CustomerFieldFactory();
			customerFieldFactory.tel1.setReadOnly(true);
			form.setFormFieldFactory(customerFieldFactory);
			
			BeanItem<Customer> beanItem = new BeanItem<Customer>(customer);
			String[] columns = {"firstname", "lastname", "idNumber", "address", "postcode", "city", "tel1" };
			form.setItemDataSource(beanItem);
			form.setVisibleItemProperties(columns);
			
			final Button saveBtn = new Button("Save");
			saveBtn.setDisableOnClick(true);
			saveBtn.addStyleName("blueButton");
			
			HorizontalLayout footer = (HorizontalLayout) form.getFooter();
			footer.setSpacing(true);
			footer.addComponent(saveBtn);
			
			newCustomerDetailLayout.addComponent(form);
			
			final CheckBox registerNewCustomer = new CheckBox("Register new customer");
			registerNewCustomer.setImmediate(true);
			newCustomerDetailLayout.addComponent(registerNewCustomer);
			
			step4.addComponent(newCustomerDetailLayout);
			
			saveBtn.addListener(new Button.ClickListener() {
	            public void buttonClick(ClickEvent event) {
	            	if(form.isValid()) {
	            		EntityManager em = app.em;
	            		try{
	            			em.getTransaction().begin();
	            			
	            			receiver = new Customer();
	            			receiver.setFirstname(form.getField("firstname").getValue().toString());
	            			receiver.setLastname(form.getField("lastname").getValue().toString());
	            			receiver.setIdNumber(form.getField("idNumber").getValue().toString());
	            			receiver.setAddress((String) form.getField("address").getValue());
	            			receiver.setPostcode((String) form.getField("postcode").getValue());
	            			receiver.setCity((String) form.getField("city").getValue());
	            			receiver.setTel1(form.getField("tel1").getValue().toString());
	            			
	            			em.persist(receiver);
	            			
	            			if((Boolean) registerNewCustomer.getValue()) {
	            				em.getTransaction().commit();
	            				app.showNotification(Constants.SUCCESSFULLY_SAVED_MESSAGE);
	            			}
	            			else
	            				em.getTransaction().rollback();
	            			
	            			continueToStep5Btn.setEnabled(true);
	            			backToStep3Btn.setEnabled(false);
	            		} catch (Exception e) {
	            			app.showNotification(Constants.ME_FORM_DATA);
	            			em.getTransaction().rollback();
	            			e.printStackTrace();
	            			saveBtn.setEnabled(true);
	            		}
	            	} else {
	            		app.showNotification(Constants.ME_FORM_FIELDS_REQUIRED);
	            		saveBtn.setEnabled(true);
	            	}
	            }
			});
		} else if(customerContainer.size() == 1) { // use found customer detail to find possible receivers and display sender info
			Panel panel = new Panel("Receiver details");
			panel.addStyleName(Runo.PANEL_LIGHT);
			receiver = customerContainer.getItem(customerContainer.firstItemId()).getEntity();
        	String customerDetials = "<ul><li>Name: <b>" +receiver.getFirstname() +" "+ receiver.getLastname() +"</b></li>" +
        					  	   "<li>Address: <b>"+ receiver.getAddress() +" "+ receiver.getCity() +"</b></li>" +
        					  	   "<li>Tel: <b>"+ receiver.getTel1() +"</b></li>" +
        					  "</ul>";
        	panel.addComponent(new Label(customerDetials, Label.CONTENT_XHTML));
        	step4.addComponent(panel);
        	continueToStep5Btn.setEnabled(true);
		} else {
			app.showNotification("This number is used by more then 1 customer.");
		}
		addComponent(step4);
		
		HorizontalLayout buttons = new HorizontalLayout();
		buttons.setSpacing(true);
		buttons.addComponent(backToStep3Btn);
		buttons.addComponent(continueToStep5Btn);
		addComponent(buttons);
	}
	
	private void loadStep5() {
		step5.removeAllComponents();
		ParcelForm pf = new ParcelForm(app, null, "Create parcel", 1);
		pf.initForm();
		pf.fieldFactory.receiverIdentification.setVisible(false);
    	pf.fieldFactory.receiverIdentificationLabel.setVisible(false);
		pf.addStyleName("createParcelForm");
		
		pf.tp.setSenderName(sender.getFirstname() +" "+ sender.getLastname());
		pf.tp.setSenderTel(sender.getTel1());
		pf.tp.setSenderIdentification(sender.getIdNumber());
		pf.tp.setReceiverName(receiver.getFirstname() +" "+ receiver.getLastname());
		pf.tp.setReceiverTel(receiver.getTel1());
		pf.tp.setReceiverIdentification(receiver.getIdNumber());
		
		pf.fieldFactory.senderName.setReadOnly(true);
		pf.fieldFactory.senderTel.setReadOnly(true);
		pf.fieldFactory.senderIdentification.setReadOnly(true);
		pf.fieldFactory.receiverName.setReadOnly(true);
		pf.fieldFactory.receiverTel.setReadOnly(true);
		pf.fieldFactory.receiverIdentification.setReadOnly(true);
		
		step5.addComponent(pf);
		addComponent(step5);
	}
	
}
